package cn.seapon.talker.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;

public class SwipeListView extends ListView {

	private static final String TAG = "SwipeListView类";

	private boolean isShown;
	//前一个点击的View的引用
	private View mPreItemView;
	//当前点击的View的引用
	private View mCurrentItemView;
	//记录下点击开始时的位置
	private float mFirstX;
	private float mFirstY;
	
	private boolean mIsHorizontal;

	public SwipeListView(Context context) {
		super(context);
	}
	public SwipeListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	public SwipeListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}


	/**
	 * 是定义于ViewGroup（继承自View）里面的一个方法
	 * 每次解除或移动屏幕时都会出发该函数 以拦截事件对象，
	 * 
	 * 可以看做预处理，可影响事件的传递方向（决定是否允许Touch事件继续向下（子控件）传递）：
	 * 	
	 * （每个手势事件都会先调用onInterceptTouchEvent）
	 * @param event 触发的事件对象
	 * @return  TRUE 代表事件在当前的viewGroup中会被处理，则向下传递之路被截断（所有子控件将没有机会参与Touch事件）
	 * 							同时把事件传递给当前的控件的onTouchEvent()处理
	 * 				  FALSE 把事件交给子控件的onInterceptTouchEvent()
	 * 
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent  event) {
		//获取触发时的位置
		float lastX = event.getX();
		float lastY = event.getY();
		switch (event.getAction()) {
			
			//按下事件
			case MotionEvent.ACTION_DOWN:
				mIsHorizontal = false;
				mFirstX = lastX;
				mFirstY = lastY;
				//通过x和y的位置来确定这个listView里面这个item的位置
				int motionPosition = pointToPosition((int) mFirstX, (int) mFirstY);
				Log.e(TAG, "onInterceptTouchEvent----->ACTION_DOWN position=" + motionPosition);
				if (motionPosition >= 0) {
					//获得该view对象
					View currentItemView = getChildAt(motionPosition - getFirstVisiblePosition());
					//保存前一个currentView的引用
					mPreItemView = mCurrentItemView;
					//保存当前的View对象的引用
					this.mCurrentItemView = currentItemView;
				}
				break;
	
			case MotionEvent.ACTION_MOVE:
				//获取当前和手指按下时位置之间的偏移
				float dx = lastX - mFirstX;
				float dy = lastY - mFirstY;
				//迁移大于
				if (Math.abs(dx) >= 5 && Math.abs(dy) >= 5) {
					//表明事件处理完事，不再传递
					return true;
				}
				break;
	
			//手指抬起事件  
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL:
				Log.i(TAG, "onInterceptTouchEvent----->ACTION_UP____ACTION_CANCEL");
				if (isShown && mPreItemView != mCurrentItemView) {
					Log.i(TAG, "1---> hiddenRight");
					/**
	                 * 情况一： 一个Item的右边布局已经显示，
	                 * 这时候点击任意一个item, 那么先前那个右边布局显示的item隐藏其右边布局
	                 */
//					hiddenRight(mPreItemView);
				}
				break;
				
			default:
				break;
		}
		//默认返回值是false
		return super.onInterceptTouchEvent(event);
	}

	/**
	 * 用于处理事件，返回值决定当前控件是否消费（consume）了这个事件，也就是说在当前控件在处理完Touch事件后，
	 * 是否还允许Touch事件继续向上（父控件）传递
	 * 
	 * @return   表示在当前控件在处理完Touch事件后，是否还允许Touch事件继续向上（父控件）传递
	 * 					FALSE - 则向上传递给父控件,自己不作处理，详细一点就是这个touch事件就给了父控件，
	 * 								那么后面的up事件就是到这里touch触发，不会在传给它的子控件。如果父控
	 * 								件依然是false，那touch的处理就给到父控件的父控件，那么up的事件处理都
	 * 								在父控件的父控件，不会触发下面的。
	 * 					TRUE - 那么它的touch事件都在这里处理，父控件是处理不了，因为它收不到子控件
	 * 								传给他的touch，被子控件给拦截了
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		float lastX = event.getX();
		float lastY = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.i(TAG, "---->ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE:
			float dx = lastX - mFirstX;
			float dy = lastY - mFirstY;
			//judge if can judge scroll direction
			mIsHorizontal = isHorizontalDirectionScroll(dx, dy);
			
			if (!mIsHorizontal) {
				break;
			}

			Log.i(TAG, "onTouchEvent ACTION_MOVE");
			
			if (mIsHorizontal) {
                if (isShown && mPreItemView != mCurrentItemView) {
                	Log.i(TAG, "2---> hiddenRight");
                    /**
                     * 情况二：
                     * 一个Item的右边布局已经显示，
                     * 这时候左右滑动另外一个item,那个右边布局显示的item隐藏其右边布局
                     * 向左滑动只触发该情况，向右滑动还会触发情况五
                     */
//                    hiddenRight(mPreItemView);
                }
			}else {
                if (isShown) {
                	Log.i(TAG, "3---> hiddenRight");
                    /**
                     * 情况三：
                     * 一个Item的右边布局已经显示，
                     * 这时候上下滚动ListView,那么那个右边布局显示的item隐藏其右边布局
                     */
//                    hiddenRight(mPreItemView);
                }
            }
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			Log.i(TAG, "============ACTION_UP");
			if (isShown) {
				Log.i(TAG, "4---> hiddenRight");
                /**
                 * 情况四：
                 * 一个Item的右边布局已经显示，
                 * 这时候左右滑动当前一个item,那个右边布局显示的item隐藏其右边布局
                 */
//                hiddenRight(mPreItemView);
            }

            if (mIsHorizontal) {
                if (mFirstX - lastX > 30) {
//                    showRight(mCurrentItemView);
                } else {
                	Log.i(TAG, "5---> hiddenRight");
                    /**
                     * 情况五：
                     * 向右滑动一个item,且滑动的距离超过了右边View的宽度的一半，隐藏之。
                     */
//                    hiddenRight(mCurrentItemView);
                }
                return true;
            }
			break;
		}

		return super.onTouchEvent(event);
	}

//	private void showRight(View rightView) {
//		RelativeLayout rl_right=(RelativeLayout)rightView.findViewById(R.id.item_right);
//		rl_right.setVisibility(View.VISIBLE);
//		isShown = true;
//	}
//
//	private void hiddenRight(View rightView) {
//		RelativeLayout rl_right=(RelativeLayout)rightView.findViewById(R.id.item_right);
//		rl_right.setVisibility(View.GONE);
//		isShown = false;
//	}

	/**
	 * 判断是否是水平方向上的移动
	 * @param dx   x轴偏移
	 * @param dy   y轴偏移
	 * @return 
	 */
	private boolean isHorizontalDirectionScroll(float dx, float dy) {
		boolean mIsHorizontal = true;

		//偏移大于30 且 单向偏移是他向偏移的两倍时  视为 该向偏移
		if (Math.abs(dx) > 30 && Math.abs(dx) > 2 * Math.abs(dy)) {
			mIsHorizontal = true;
		} else if (Math.abs(dy) > 30 && Math.abs(dy) > 2 * Math.abs(dx)) {
			mIsHorizontal = false;
			System.out.println("mIsHorizontal---->" + mIsHorizontal);
		}

		return mIsHorizontal;
	}
	
}
